﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Graphics;

namespace Projet_Synthese
{
    public abstract class FormeGeometrique
    {
        public static float PI2 = MathHelper.Pi * 2;
        public static float THETAANGLE = 0.2f;
        public bool IgnoreRotation { get; set;}
        public bool IgnorePlacement { get; set; }
        public FormeGeometrique(Texture2D[] texture,int idTexture,Rectangle source,Rectangle destination)
        {
            if (idTexture < 1 || idTexture > 5)
                throw new InvalidOperationException("Erreur sur l'idTexture");
            this.idTexture = idTexture;
            sourceTexture = texture;
            RectangleSource = source;
            RectangleDestination = destination;
            EstBase = false;
            Rotation = 0;
            origine = new Vector2(Texture.Width / 2, Texture.Height / 2);
            EstSelectionné = false;
            EstGrisé = false;
            IgnoreRotation = false;
            IgnorePlacement = false;
        }
        public abstract String Name { get;}

        private Texture2D[] sourceTexture;
        private int idTexture = 0;
        public Rectangle RectangleSource
        {
            get;
            set;
        }
        public Rectangle RectangleDestination;
      
        public Texture2D Texture
        {
            get
            {
                if (EstSelectionné)
                    return sourceTexture[10 - idTexture];
                else if(EstGrisé)
                    return sourceTexture[15 - idTexture];
                else if(EstBase)
                    return sourceTexture[20 - idTexture];
                return sourceTexture[5-idTexture];
            }
        }

        public bool EstSelectionné
        {
            get;
            set;
        }

        public bool EstGrisé
        {
            get;
            set;
        }

        public bool EstBase
        {
            get;

            set;
        }
        protected Vector2 origine;
        private double Theta = 10;

        public Vector2 Origine
        {
            get { return origine; }
            set { origine = value; }
        }
        public float Rotation
        {
            get;
            set;
        }

        public abstract int Surface
        {
            get;
        }

        public void Draw(SpriteBatch sprite)
        {
            sprite.Draw(Texture, RectangleDestination, RectangleSource, Color.White,Rotation,origine,SpriteEffects.None,1f);
        }

        public void RotationForme(float roration)
        {
            this.Rotation += roration;
            float circle = MathHelper.Pi * 2;
            this.Rotation = this.Rotation % circle;
        }
        protected virtual bool testProcheAvecRotation(float angle1, float angle2)
        {
            float diffRatation = Math.Abs(angle1 - angle2) % PI2 ;
            Console.WriteLine(diffRatation);
            return diffRatation < THETAANGLE || Math.Abs(diffRatation - PI2) < THETAANGLE;
        }
        public bool Equals(FormeGeometrique form)
        {
            if (form.Texture.Tag != Texture.Tag)
                return false;
            if (IgnoreRotation)
                form.Rotation = Rotation;
            if ( (IgnorePlacement || testProche(RectangleDestination.Center, form.RectangleDestination.Center)) &&
                (testProcheAvecRotation(Rotation,form.Rotation)))
                return true;
            return false;
        }

        private bool testProche(Point point, Point point_2)
        {
            
            return Math.Abs(point.X - point_2.X) <= (double)Theta && Math.Abs(point.Y - point_2.Y) <= (double)Theta;
        }
        public override bool Equals(object obj)
        {
            if (ReferenceEquals(this, obj)) return true;
            return Equals(obj as FormeGeometrique);
        }

        public override int GetHashCode()
        {
            return base.GetHashCode() + Texture.LevelCount * Texture.Width * Texture.Height - (int)Rotation * Surface;
        }
        public static bool operator ==(FormeGeometrique form1, FormeGeometrique form2)
        {
            if (ReferenceEquals(form1, null) || ReferenceEquals(form2, null))
                return ReferenceEquals(form1, form2);
            return form1.Equals(form2);
        }

        public static bool operator !=(FormeGeometrique form1, FormeGeometrique form2)
        {
            if (ReferenceEquals(form1, null) || ReferenceEquals(form2, null))
                return !ReferenceEquals(form1, form2);
            return !form1.Equals(form2);
        }
    }
}
